/*
 * @FileName: bsp_pwm.c
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-07-12 16:05:59
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-05 14:47:24
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#include "bsp_pwm.h"
#include "bsp_gpio.h"

static void pwm_clk_config(void)
{
    RCC_TIM1_8_Clock_Config(RCC_TIM1_8_CLKSRC_SYSCLK); // 定时器时钟选择SYSLCK = 128MHz
    RCC_APB2_Peripheral_Clock_Enable(RCC_APB2_PERIPH_TIM1);
}

static void pwm_timebase_config(void)
{
    TIM_TimeBaseInitType TIM_TimeBaseStructure;

    TIM_Base_Struct_Initialize(&TIM_TimeBaseStructure);
    TIM_TimeBaseStructure.Period    = BSP_TIMER_CNT_RELOAD;
    TIM_TimeBaseStructure.Prescaler = 0;
    TIM_TimeBaseStructure.ClkDiv    = 0;
    TIM_TimeBaseStructure.CntMode   = TIM_CNT_MODE_UP; // 计数器中心对称模式
    TIM_Base_Initialize(TIM1, &TIM_TimeBaseStructure);
}

static void pwm_channel_config(void)
{
    OCInitType TIM_OCInitStructure;
    TIM_BDTRInitType TIM_BDTRInitStructure;
    
    TIM_Off(TIM1);

    TIM_Output_Channel_Struct_Initialize(&TIM_OCInitStructure);

    // PWM通道基本配置
    TIM_OCInitStructure.OcMode       = TIM_OCMODE_PWM1;
    TIM_OCInitStructure.OutputState  = TIM_OUTPUT_STATE_ENABLE;
    TIM_OCInitStructure.OutputNState = TIM_OUTPUT_NSTATE_ENABLE;
    TIM_OCInitStructure.Pulse        = 0;
    // CH3 控制HB2
    TIM_OCInitStructure.OcPolarity   = TIM_OC_POLARITY_HIGH;     //设置PWM上管有效电平为低电平
    TIM_OCInitStructure.OcNPolarity  = TIM_OCN_POLARITY_HIGH;    //设置PWM下管有效电平为低电平
    TIM_OCInitStructure.OcIdleState  = TIM_OC_IDLE_STATE_SET;   // 上管空闲时输出有效电平
    TIM_OCInitStructure.OcNIdleState = TIM_OCN_IDLE_STATE_SET;  // 下管空闲时输出有效电平
    TIM_Output_Channel3_Initialize(TIM1, &TIM_OCInitStructure);
    TIM_Output_Channel3_Preload_Set(TIM1, TIM_OC_PRELOAD_ENABLE);
    // CH4 控制HB1
    TIM_OCInitStructure.OcPolarity   = TIM_OC_POLARITY_HIGH;        //设置PWM上管输出有效极性
    TIM_OCInitStructure.OcNPolarity  = TIM_OCN_POLARITY_HIGH;       //设置PWM下管输出有效极性
    TIM_OCInitStructure.OcIdleState  = TIM_OC_IDLE_STATE_RESET;     // 上管空闲时设置为无效电平
    TIM_OCInitStructure.OcNIdleState = TIM_OCN_IDLE_STATE_RESET;    // 下管空闲时设置为无效电平
    TIM_Output_Channel4_Initialize(TIM1, &TIM_OCInitStructure);
    TIM_Output_Channel4_Preload_Set(TIM1, TIM_OC_PRELOAD_ENABLE);


    // 设置OC5脉冲，用于比较器消隐
    TIM_OCInitStructure.OcMode       = TIM_OCMODE_PWM1; // 上管开通开始消隐
    TIM_OCInitStructure.Pulse        = 5; // 消隐5个PWM时钟
    TIM_Output_Channel5_Initialize(TIM1, &TIM_OCInitStructure);
    TIM_Output_Channel5_Preload_Set(TIM1, TIM_OC_PRELOAD_ENABLE);

    /* Automatic Output enable, Break, dead time and lock configuration*/
    TIM_Break_And_Dead_Time_Struct_Initialize(&TIM_BDTRInitStructure);    //结构体初始化设置
    TIM_BDTRInitStructure.OssrState       = TIM_OSSR_STATE_DISABLE; // 使能后，定时器
    TIM_BDTRInitStructure.OssiState       = TIM_OSSI_STATE_DISABLE;
    TIM_BDTRInitStructure.LockLevel       = TIM_LOCK_LEVEL_OFF;
    TIM_BDTRInitStructure.DeadTime        = BSP_PWM_DEADTIME;
    TIM_BDTRInitStructure.Break           = TIM_BREAK_IN_ENABLE;
    TIM_BDTRInitStructure.BreakPolarity   = TIM_BREAK_POLARITY_HIGH;
    TIM_BDTRInitStructure.AutomaticOutput = TIM_AUTO_OUTPUT_DISABLE;
    TIM_BDTRInitStructure.IomBreakEn      = true; // 刹车信号来自内部比较器
    TIM_BDTRInitStructure.LockUpBreakEn   = true;
    TIM_BDTRInitStructure.PvdBreakEn      = true;
    TIM_Break_And_Dead_Time_Set(TIM1, &TIM_BDTRInitStructure);    /*死区设置*/
    TIM_Break_Filter_Disable(TIM1);
//    TIM_Output_Trigger_Select(TIM1, TIM_TRGO_SRC_OC2REF);  /*输出ADC转换出发信号*/

//    // updata事件触发ADC转换，中心对称模式时，计数器等于0和等于PRD都会生成updata事件
    TIM_Output_Trigger_Select(TIM1, TIM_TRGO_SRC_UPDATE);
    TIM_Update_Event_Enable(TIM1);

    TIM_Event_Generate(TIM1, TIM_EVT_SRC_UPDATE);
////    bsp_pwm_output_disable(); // 关闭所有PWM
    TIM_On(TIM1);    // 启动定时器1

}

/**
 * @description: pwm初始化
 * @return 无
 */
void bsp_pwm_init(void)
{
    pwm_clk_config();
    pwm_timebase_config();
    pwm_channel_config();
}
